/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict'

angular.module('flowableApp').controller('StartProcessController', [
  '$rootScope',
  '$scope',
  '$translate',
  '$http',
  '$timeout',
  '$location',
  '$route',
  '$modal',
  '$routeParams',
  '$q',
  'AppDefinitionService',
  'ProcessService',
  'FormService',
  'RelatedContentService',
  function(
    $rootScope,
    $scope,
    $translate,
    $http,
    $timeout,
    $location,
    $route,
    $modal,
    $routeParams,
    $q,
    AppDefinitionService,
    ProcessService,
    FormService,
    RelatedContentService
  ) {
    $scope.appDefinitionKey = $routeParams.appDefinitionKey
    $scope.missingAppdefinition = $scope.appDefinitionKey === false

    AppDefinitionService.setActiveAppDefinitionKey($scope.appDefinitionKey)

    ProcessService.getProcessDefinitions($scope.appDefinitionKey).then(function(response) {
      $scope.processDefinitions = response.data
    })

    $scope.processName = ''
    $scope.processDefinition = null
    $scope.processDefinitionWithStartFormId = null
    $scope.startFormDefinition = null

    // Support for prepopulating upload fields
    if (FLOWABLE.CONFIG.workflow && FLOWABLE.CONFIG.workflow.addStartProcessContent) {
      $scope.startProcessContent = FLOWABLE.CONFIG.workflow.addStartProcessContent
      $scope.startProcessContentQueued = false
    }
    $scope.addedStartProcessContent = null

    $scope.selectProcessDefinition = function(definition) {
      if ($scope.processDefinition == definition) {
        // deselect workflow
        $scope.processDefinition = null
        $scope.processDefinitionWithStartFormId = null
        $scope.startFormDefinition = null
      } else {
        $scope.processDefinition = definition
        if (definition.hasStartForm) {
          $scope.loadStartForm(definition)
        } else {
          $scope.processName = definition.name + ' - ' + new moment().format('MMMM Do YYYY')
          $scope.processDefinitionWithStartFormId = null
          $scope.startFormDefinition = null
        }
      }
    }

    $scope.loadStartForm = function() {
      // First lets see if there is any content that shall be added to the start form
      if (!$scope.startProcessContent) {
        // No content shall be added, just show the form
        $scope.setStartForm()
      } else if ($scope.startProcessContent) {
        // Start form shall be pre-populated with files
        if ($scope.addedStartProcessContent) {
          // Content has already been added, lets show the start form
          $scope.setStartForm()
        } else {
          // All content has not been added yet but is it being queued?
          if ($scope.startProcessContentQueued) {
            // The content is being queued and added right now, don't do anything.
            // When the queue is finished and setForm is called, it will use the last selected
            // process definition
          } else {
            // Lets queue the content to be added
            $scope.startProcessContentQueued = true
            if (typeof $scope.startProcessContent == 'function') {
              // Instead of the actual content that hsall be added a function was provided,
              // let it load the content so we can add it afterwards
              $scope.startProcessContent(
                function(content) {
                  // Replace the loader function with data
                  $scope.startProcessContent = content

                  // Add the data
                  $scope.queueStartProcessContent().then(function() {
                    $scope.setStartForm()
                  })
                },
                function(code, msg) {
                  $rootScope.addAlert(msg, 'error')
                }
              )
            } else {
              // the data to be added is there, then add id
              $scope.queueStartProcessContent().then(function() {
                $scope.setStartForm()
              })
            }
          }
        }
      } else {
        // Content is already being added to the start form, lets make
      }
    }

    $scope.queueStartProcessContent = function() {
      var addedContent = []
      var deferred = $q.defer()
      var contentToAdd = $scope.startProcessContent
      var content
      for (var i = 0; i < contentToAdd.length; i++) {
        content = contentToAdd[i]
        RelatedContentService.addRelatedContentFromSource(
          null,
          null,
          content.source,
          content.sourceId,
          content.name,
          content.link
        ).then(
          function(result) {
            addedContent.push(result)
            if (addedContent.length == contentToAdd.length) {
              $scope.addedStartProcessContent = addedContent
              deferred.resolve()
            }
          },
          function(error) {
            $rootScope.addAlert(
              $translate('PROCESS.ALERT.START-PROCESS-CONTENT-ADD-FAILED', { noOfFiles: contentToAdd.length }),
              'error'
            )
            deferred.reject()
          }
        )
      }
      return deferred.promise
    }

    $scope.setStartForm = function() {
      var definition = $scope.processDefinition
      if (definition.hasStartForm) {
        // Load start form
        FormService.getStartForm(definition.id).then(function(formData) {
          // Merge in the content to become pre-populated upload fields
          if ($scope.addedStartProcessContent) {
            var field
            var allFormFields = formData.fields
            for (var index in allFormFields) {
              field = allFormFields[index]
              if (field.type == 'upload') {
                field.value = $scope.addedStartProcessContent
                break
              }
            }
          }

          $scope.processName = definition.name + ' - ' + new moment().format('MMMM Do YYYY')
          $scope.processDefinition = definition
          $scope.processDefinitionWithStartFormId = definition.id
          $scope.startFormDefinition = formData
        })
      }
    }

    $scope.navigateToView = function(view) {
      if ($scope.appDefinitionKey && !FLOWABLE.CONFIG.integrationProfile) {
        $location.path('/apps/' + encodeURIComponent($scope.appDefinitionKey) + view)
      } else {
        $location.path(view)
      }
    }

    $scope.createProcessInstance = function() {
      ProcessService.createProcess({
        processDefinitionId: $scope.processDefinition.id,
        name: $scope.processName
      }).then(function() {
        $scope.navigateToView('/processes')
      })
    }

    var unregisterProcessStartedCallback = $scope.$on('process-started', function(event, data) {
      unregisterProcessStartedCallback()
      $scope.navigateToView('/processes')
    })
  }
])
